package com.psbc.data.trans.datasource.pg.service.impl;

import cn.hutool.core.io.FileUtil;
import com.psbc.data.trans.common.Constants;
import com.psbc.data.trans.common.DatabaseEnum;
import com.psbc.data.trans.common.XmlLabel;
import com.psbc.data.trans.common.exception.BusinessException;
import com.psbc.data.trans.common.utils.XmlDataUtil;
import com.psbc.data.trans.datasource.pg.entity.Columns;
import com.psbc.data.trans.datasource.pg.entity.TbInterfaceSend;
import com.psbc.data.trans.datasource.pg.mapper.AlertHistoryMapper;
import com.psbc.data.trans.datasource.pg.mapper.ColumnsMapper;
import com.psbc.data.trans.datasource.pg.service.FileGenerateService;
import com.psbc.data.trans.vo.XmlDataHeadVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.core.io.support.ResourcePatternResolver;
import org.springframework.stereotype.Service;

import javax.sql.DataSource;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.text.SimpleDateFormat;
import java.util.List;

@Service
@Slf4j
public class FileGenerateServiceImpl implements FileGenerateService {

    @Autowired
    private ColumnsMapper columnsMapper;

    @Autowired
    private AlertHistoryMapper alertHistoryMapper;

    private ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();

    // 根据接口表信息生成DataSource
    @Override
    public DataSource configureDataSource(TbInterfaceSend interfaceSend) {
        String databaseType = interfaceSend.getDatabaseType();
        if(DatabaseEnum.getByDatabaseType(databaseType)==null){
            log.error("不支持的数据库类型{}",databaseType);
            throw new BusinessException("不支持的数据库类型");
        }

        return DataSourceBuilder.create()
                .url(interfaceSend.getDatabaseUrl()+interfaceSend.getDatabaseName())//url
                .username(interfaceSend.getDatabaseUser())//用户名
                .password(interfaceSend.getDatabasePwd())//密码
                .driverClassName(DatabaseEnum.getByDatabaseType(databaseType).getDatabaseJdbcDriver())//驱动类
                .build();
    }

    @Override
    public void generateFile(TbInterfaceSend interfaceSend) {

        // 将生成一份新的模板文件到目标文件夹
        String templateFilePath = Constants.EDB_TEMPLATE_FILE_PATH;
        String targetDirectory = Constants.EDB_DESTINATION_FILE_FOLDER;
        String copiedFilePath = targetDirectory + "target.xml";
        FileUtil.copy(templateFilePath, copiedFilePath, true);

        // 加载数据库驱动

        // 填充模板文件的xml中的header头
        XmlDataHeadVO xmlDataHeadVO = new XmlDataHeadVO();
        xmlDataHeadVO.setDataName(interfaceSend.getDatabaseName()+"-"+interfaceSend.getTableName());// 接口库名/用户名-数据接口名称 (例:LOAN-TB_CON_FLOW)
        xmlDataHeadVO.setPrimaryKey(interfaceSend.getTablePk());
        xmlDataHeadVO.setUpdateFlag("N");
        xmlDataHeadVO.setDeleteFlag("N");
        xmlDataHeadVO.setDataType(interfaceSend.getInterfaceType());

        XmlDataUtil.setXmlDataHead(copiedFilePath, xmlDataHeadVO);


    }

    @Override
    public void generateControlFile(TbInterfaceSend interfaceSend) throws IOException {
        // 获取接口名
        String interfaceName = interfaceSend.getDatabaseName().toUpperCase() + "-" + interfaceSend.getTableName().toUpperCase();
        FileGenerateServiceImpl.log.info(interfaceName);
        // 拼接需要扫描的文件名
        String scanFileName = interfaceSend.getLocalSysCode() + "_" + interfaceName + XmlLabel.CONTROL_FILE_FLAG + new SimpleDateFormat("yyyyMMdd").format(interfaceSend.getStartDate())
                + "_" + interfaceSend.getInterfaceType();
        FileGenerateServiceImpl.log.info(scanFileName);
        // 控制文件名
        String controlFileName = interfaceSend.getLocalSysCode() + "_" + interfaceName + XmlLabel.CONTROL_FILE_FLAG + new SimpleDateFormat("yyyyMMdd").format(interfaceSend.getStartDate())
                + "_" + interfaceSend.getInterfaceType() + XmlLabel.CONTROL_FILE_END;
        FileGenerateServiceImpl.log.info(controlFileName);
        // 扫描指定路径下的数据文件
        Resource[] resources = resolver.getResources(Constants.EDB_DESTINATION_FILE_FOLDER + "/" + scanFileName);

        String destinationFile = Constants.EDB_DESTINATION_FILE_FOLDER + "/" + controlFileName;

        StringBuilder contentBuilder = new StringBuilder();

        for (Resource resource : resources) {
            // 获取文件名
            String fileName = resource.getFilename();
            // 获取文件大小
            String fileSize = String.valueOf(resource.contentLength());
            // 数据日期
            String date = new SimpleDateFormat("yyyyMMdd").format(interfaceSend.getStartDate());

            // 内容写入文件
            String fileLine = String.join(" ", fileName, fileSize, date);

            contentBuilder.append(fileLine).append("\n");

        }

        String line = contentBuilder.toString().trim();

        Files.write(Paths.get(destinationFile),line.getBytes());
    }

    @Override
    public void generateCheckFile(TbInterfaceSend interfaceSend) throws IOException {
        // 接口名
        String interfaceName = interfaceSend.getDatabaseName().toUpperCase() + "-" + interfaceSend.getTableName().toUpperCase();
        // 生成数据校验文件名
        String checkFileName = interfaceSend.getLocalSysCode() + "_" + interfaceName + XmlLabel.CONTROL_FILE_FLAG + new SimpleDateFormat("yyyyMMdd").format(interfaceSend.getStartDate())
                + "_" + interfaceSend.getInterfaceType() + XmlLabel.CHECK_FILE_END;
        // 检验文件目标地址
        String copiedFilePath = Constants.EDB_DESTINATION_FILE_FOLDER + "/" + checkFileName;

        // 获取接口名
        String dataName = interfaceSend.getDatabaseName().toUpperCase() + "-" + interfaceSend.getTableName().toUpperCase();
        // 主键
        String primaryKey = interfaceSend.getDatabaseName().toUpperCase() + "," + interfaceSend.getTableName().toUpperCase() + "," + interfaceSend.getStartDate();
        // 抽数类型
        String loadDataType = interfaceSend.getInterfaceType();
        // 字段数
        List<Columns> columns = columnsMapper.selectByTableName(interfaceSend.getTableName());
        int fieldNum = columns.size();
        // 库名
        String dbName = interfaceSend.getDatabaseName().toUpperCase();
        // 表名
        String tableName = interfaceSend.getTableName().toUpperCase();
        //表类型
        String tableType = interfaceSend.getTableType();
        // 开始时间
        String startDate = new SimpleDateFormat("yyyy-MM-dd").format(interfaceSend.getStartDate());
        // 结束时间
        String endDate = new SimpleDateFormat("yyyy-MM-dd").format(interfaceSend.getEndDate());
        // 状态数据
        String stateValue = String.valueOf(alertHistoryMapper.selectCount());

        // 数据拼接
        // 填充模板文件的xml中的header头
        XmlDataHeadVO<Columns> xmlDataHeadVO = new XmlDataHeadVO();
        xmlDataHeadVO.setDataName(dataName);// 接口库名/用户名-数据接口名称 (例:LOAN-TB_CON_FLOW)
        xmlDataHeadVO.setPrimaryKey(primaryKey);
        xmlDataHeadVO.setDataType(loadDataType);
        xmlDataHeadVO.setFieldNum(fieldNum);
        xmlDataHeadVO.setColumns(columns);
        xmlDataHeadVO.setRowNum(1);
        xmlDataHeadVO.setPageNum(1);

        StringBuilder contentBuilder = new StringBuilder();
        // 内容写入文件
        String fileLine = String.join(XmlLabel.PAGE_TEXT_FLAG_NOUN, dbName, tableName, tableType, startDate,
                endDate, "count(*)", stateValue, "备注信息");

        contentBuilder.append(fileLine).append(XmlLabel.PAGE_TEXT_FLAG_END);

        String dataLine = contentBuilder.toString().trim();

        xmlDataHeadVO.setDataBody(dataLine);

        XmlDataUtil.setXmlDataHead(Constants.EDB_CHK_TEMPLATE_FILE_PATH, xmlDataHeadVO);

        XmlDataUtil.creatFieldXml(Constants.EDB_CHK_TEMPLATE_FILE_PATH, copiedFilePath, xmlDataHeadVO);
    }

}
